// IO函子的问题的解决 ——IO Monad
const fp = require("lodash/fp");
const fs = require("fs");

class IO {
  static of(value) {
    return new IO(function () {
      return value;
    });
  }

  constructor(fn) {
    this._value = fn;
  }

  map(fn) {
    return new IO(fp.flowRight(fn, this._value));
  }

  join() {
    return this._value();
  }

  flatMap(fn) {
    return this.map(fn).join();
  }
}

let readFile = function (filename) {
  return new IO(function () {
    return fs.readFileSync(filename, "utf-8");
  });
};

let print = function (x) {
  return new IO(function () {
    console.log(x);
    return x;
  });
};

// let cat = fp.flowRight(print, readFile);

// let r = cat("package-lock.json")._value()._value(); // 看起来很丑
// console.log(r);

let r = readFile("package-lock.json")
  // .map((x) => x.toUpperCase())
  .map(fp.toUpper)
  .flatMap(print)
  .join();

console.log(r);
